// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.network.packets;

import java.nio.ByteBuffer;
import zombie.characters.IsoGameCharacter;
import zombie.characters.IsoZombie;
import zombie.core.network.ByteBufferWriter;
import zombie.core.raknet.UdpConnection;
import zombie.core.skinnedmodel.visual.HumanVisual;
import zombie.debug.DebugLog;
import zombie.debug.LogSeverity;
import zombie.iso.IsoDirections;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoMovingObject;
import zombie.iso.IsoWorld;
import zombie.iso.objects.IsoDeadBody;
import zombie.network.GameClient;
import zombie.network.GameServer;
import zombie.network.ServerMap;

public abstract class DeadCharacterPacket implements INetworkPacket {
    public short id;
    protected float x;
    protected float y;
    protected float z;
    protected float angle;
    protected IsoDirections direction;
    protected byte characterFlags;
    protected IsoGameCharacter killer;
    protected IsoGameCharacter character;

    public void set(IsoGameCharacter _character) {
        this.character = _character;
        this.id = _character.getOnlineID();
        this.killer = _character.getAttackedBy();
        this.x = _character.getX();
        this.y = _character.getY();
        this.z = _character.getZ();
        this.angle = _character.getAnimAngleRadians();
        this.direction = _character.getDir();
        this.characterFlags = (byte)(_character.isFallOnFront() ? 1 : 0);
    }

    public void process() {
        if (this.character != null) {
            IsoGridSquare isoGridSquare = IsoWorld.instance.CurrentCell.getGridSquare((double)this.x, (double)this.y, (double)this.z);
            if (this.character.getCurrentSquare() != isoGridSquare) {
                DebugLog.Multiplayer
                    .warn(
                        String.format(
                            "Corpse %s(%d) teleport: position (%f ; %f) => (%f ; %f)",
                            this.character.getClass().getSimpleName(),
                            this.id,
                            this.character.x,
                            this.character.y,
                            this.x,
                            this.y
                        )
                    );
                this.character.setX(this.x);
                this.character.setY(this.y);
                this.character.setZ(this.z);
            }

            if (this.character.getAnimAngleRadians() - this.angle > 1.0E-4F) {
                DebugLog.Multiplayer
                    .warn(
                        String.format(
                            "Corpse %s(%d) teleport: direction (%f) => (%f)",
                            this.character.getClass().getSimpleName(),
                            this.id,
                            this.character.getAnimAngleRadians(),
                            this.angle
                        )
                    );
                if (this.character.hasAnimationPlayer()
                    && this.character.getAnimationPlayer().isReady()
                    && !this.character.getAnimationPlayer().isBoneTransformsNeedFirstFrame()) {
                    this.character.getAnimationPlayer().setAngle(this.angle);
                } else {
                    this.character.getForwardDirection().setDirection(this.angle);
                }
            }

            boolean _boolean = (this.characterFlags & 1) != 0;
            if (_boolean != this.character.isFallOnFront()) {
                DebugLog.Multiplayer
                    .warn(
                        String.format(
                            "Corpse %s(%d) teleport: pose (%s) => (%s)",
                            this.character.getClass().getSimpleName(),
                            this.id,
                            this.character.isFallOnFront() ? "front" : "back",
                            _boolean ? "front" : "back"
                        )
                    );
                this.character.setFallOnFront(_boolean);
            }

            this.character.setCurrent(isoGridSquare);
            this.character.dir = this.direction;
            this.character.setAttackedBy(this.killer);
            this.character.becomeCorpse();
        }
    }

    @Override
    public void parse(ByteBuffer b, UdpConnection connection) {
        this.id = b.getShort();
        this.x = b.getFloat();
        this.y = b.getFloat();
        this.z = b.getFloat();
        this.angle = b.getFloat();
        this.direction = IsoDirections.fromIndex(b.get());
        this.characterFlags = b.get();
        byte _byte = b.get();
        short _short = -1;
        if (GameServer.bServer) {
            switch (_byte) {
                case 0:
                    this.killer = null;
                    break;
                case 1:
                    _short = b.getShort();
                    this.killer = ServerMap.instance.ZombieMap.get(_short);
                    break;
                case 2:
                    _short = b.getShort();
                    this.killer = (IsoGameCharacter)GameServer.IDToPlayerMap.get(_short);
                    break;
                default:
                    Exception exception0 = new Exception("killerIdType:" + _byte);
                    exception0.printStackTrace();
            }
        } else {
            switch (_byte) {
                case 0:
                    this.killer = null;
                    break;
                case 1:
                    _short = b.getShort();
                    this.killer = GameClient.IDToZombieMap.get(_short);
                    break;
                case 2:
                    _short = b.getShort();
                    this.killer = (IsoGameCharacter)GameClient.IDToPlayerMap.get(_short);
                    break;
                default:
                    Exception exception1 = new Exception("killerIdType:" + _byte);
                    exception1.printStackTrace();
            }
        }
    }

    protected IsoDeadBody getDeadBody() {
        IsoGridSquare isoGridSquare = IsoWorld.instance.CurrentCell.getGridSquare((double)this.x, (double)this.y, (double)this.z);
        if (isoGridSquare != null) {
            for (IsoMovingObject isoMovingObject : isoGridSquare.getStaticMovingObjects()) {
                if (isoMovingObject instanceof IsoDeadBody && ((IsoDeadBody)isoMovingObject).getOnlineID() == this.id) {
                    return (IsoDeadBody)isoMovingObject;
                }
            }
        }

        return null;
    }

    protected void parseDeadBodyInventory(IsoDeadBody isoDeadBody, ByteBuffer byteBuffer) {
        String string = isoDeadBody.readInventory(byteBuffer);
        isoDeadBody.getContainer().setType(string);
    }

    protected void parseDeadBodyHumanVisuals(IsoDeadBody isoDeadBody, ByteBuffer byteBuffer) {
        HumanVisual humanVisual = isoDeadBody.getHumanVisual();
        if (humanVisual != null) {
            try {
                humanVisual.load(byteBuffer, IsoWorld.getWorldVersion());
            } catch (Exception exception) {
                DebugLog.Multiplayer.printException(exception, "Parse dead body HumanVisuals failed", LogSeverity.Error);
            }
        }
    }

    protected void parseCharacterInventory(ByteBuffer byteBuffer) {
        if (this.character != null) {
            if (this.character.getContainer() != null) {
                this.character.getContainer().clear();
            }

            if (this.character.getInventory() != null) {
                this.character.getInventory().clear();
            }

            if (this.character.getWornItems() != null) {
                this.character.getWornItems().clear();
            }

            if (this.character.getAttachedItems() != null) {
                this.character.getAttachedItems().clear();
            }

            this.character.getInventory().setSourceGrid(this.character.getCurrentSquare());
            String string = this.character.readInventory(byteBuffer);
            this.character.getInventory().setType(string);
            this.character.resetModelNextFrame();
        }
    }

    protected void writeCharacterInventory(ByteBufferWriter byteBufferWriter) {
        if (this.character != null) {
            this.character.writeInventory(byteBufferWriter.bb);
        }
    }

    protected void writeCharacterHumanVisuals(ByteBufferWriter byteBufferWriter) {
        if (this.character != null) {
            int _int = byteBufferWriter.bb.position();
            byteBufferWriter.putByte((byte)1);

            try {
                byteBufferWriter.putBoolean(this.character.isFemale());
                this.character.getVisual().save(byteBufferWriter.bb);
            } catch (Exception exception) {
                byteBufferWriter.bb.put(_int, (byte)0);
                DebugLog.Multiplayer.printException(exception, "Write character HumanVisuals failed", LogSeverity.Error);
            }
        }
    }

    protected void parseCharacterHumanVisuals(ByteBuffer byteBuffer) {
        byte _byte = byteBuffer.get();
        if (this.character != null && _byte != 0) {
            try {
                this.character.setFemale(byteBuffer.get() != 0);
                this.character.getVisual().load(byteBuffer, IsoWorld.getWorldVersion());
            } catch (Exception exception) {
                DebugLog.Multiplayer.printException(exception, "Parse character HumanVisuals failed", LogSeverity.Error);
            }
        }
    }

    @Override
    public void write(ByteBufferWriter b) {
        b.putShort(this.id);
        b.putFloat(this.x);
        b.putFloat(this.y);
        b.putFloat(this.z);
        b.putFloat(this.angle);
        b.putByte((byte)this.direction.index());
        b.putByte(this.characterFlags);
        if (this.killer == null) {
            b.putByte((byte)0);
        } else {
            if (this.killer instanceof IsoZombie) {
                b.putByte((byte)1);
            } else {
                b.putByte((byte)2);
            }

            b.putShort(this.killer.getOnlineID());
        }
    }

    @Override
    public String getDescription() {
        String string = this.getDeathDescription() + "\n\t";
        if (this.character != null) {
            string = string + " isDead=" + this.character.isDead();
            string = string + " isOnDeathDone=" + this.character.isOnDeathDone();
            string = string + " isOnKillDone=" + this.character.isOnKillDone();
            string = string + " | health=" + this.character.getHealth();
            if (this.character.getBodyDamage() != null) {
                string = string + " | bodyDamage=" + this.character.getBodyDamage().getOverallBodyHealth();
            }

            string = string
                + " | states=( "
                + this.character.getPreviousActionContextStateName()
                + " > "
                + this.character.getCurrentActionContextStateName()
                + " )";
        }

        return string;
    }

    public String getDeathDescription() {
        return this.getClass().getSimpleName()
            + " id("
            + this.id
            + ") | killer="
            + (this.killer == null ? "Null" : this.killer.getClass().getSimpleName() + "(" + this.killer.getOnlineID() + ")")
            + " | pos=(x="
            + this.x
            + ",y="
            + this.y
            + ",z="
            + this.z
            + ";a="
            + this.angle
            + ") | dir="
            + this.direction.name()
            + " | isFallOnFront="
            + ((this.characterFlags & 1) != 0);
    }

    @Override
    public boolean isConsistent() {
        return this.character != null;
    }
}
